﻿using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using JelleDruyts.Windows;
using Schedulr.Infrastructure;
using Schedulr.Models;
using Schedulr.Models.Legacy;

namespace Schedulr.Providers
{
    /// <summary>
    /// Provides the configuration for Schedulr.
    /// </summary>
    public static class SchedulrConfigurationProvider
    {
        #region Load

        /// <summary>
        /// Loads the configuration from the default file location, or creates a new configuration instance if the file does not exist or could not be loaded.
        /// </summary>
        public static SchedulrConfiguration LoadOrCreate()
        {
            SchedulrConfiguration configuration = null;
            if (File.Exists(PathProvider.ConfigurationFilePath))
            {
                try
                {
                    configuration = Load(PathProvider.ConfigurationFilePath);
                }
                catch (Exception exc)
                {
                    Logger.Log("An error occurred while loading the configuration", exc);
                }
            }
            if (configuration == null)
            {
                configuration = new SchedulrConfiguration();
            }
            return configuration;
        }

        /// <summary>
        /// Loads the configuration from the default file location.
        /// </summary>
        public static SchedulrConfiguration Load()
        {
            return Load(PathProvider.ConfigurationFilePath);
        }

        /// <summary>
        /// Loads the configuration from the specified file location.
        /// </summary>
        /// <param name="fileName">The name of the file that contains the configuration.</param>
        public static SchedulrConfiguration Load(string fileName)
        {
            if (!File.Exists(fileName))
            {
                throw new ArgumentException("The specified configuration file does not exist: " + fileName);
            }

            try
            {
                Logger.Log("Loading configuration from file: " + fileName, TraceEventType.Verbose);
                var config = SerializationProvider.Read<SchedulrConfiguration>(fileName);

                // Fix for adding UISettings if it doesn't exist yet.
                if (config.UISettings == null)
                {
                    config.UISettings = new UISettings();
                }

                return config;
            }
            catch (Exception exc)
            {
                Logger.Log("Error while loading configuration", exc);
                throw;
            }
        }

        #endregion

        #region Save

        /// <summary>
        /// Saves the configuration to the default file location.
        /// </summary>
        /// <param name="configuration">The configuration to save.</param>
        public static void Save(SchedulrConfiguration configuration)
        {
            Save(configuration, PathProvider.ConfigurationFilePath);
        }

        /// <summary>
        /// Saves the configuration to the specified file location.
        /// </summary>
        /// <param name="configuration">The configuration to save.</param>
        /// <param name="fileName">The name of the file to which to save the configuration.</param>
        public static void Save(SchedulrConfiguration configuration, string fileName)
        {
            try
            {
                Logger.Log("Saving configuration to file: " + fileName, TraceEventType.Verbose);
                SerializationProvider.Write<SchedulrConfiguration>(configuration, fileName);
            }
            catch (Exception exc)
            {
                Logger.Log("Error while saving configuration", exc);
                throw;
            }
        }

        #endregion

        #region ImportFromLegacyConfiguration

        /// <summary>
        /// Imports queued pictures from a legacy configuration file.
        /// </summary>
        /// <param name="account">The account into which to import the queued pictures.</param>
        /// <param name="fileName">The name of the legacy configuration file.</param>
        /// <returns>The number of queued pictures that were imported.</returns>
        public static int ImportFromLegacyConfiguration(Account account, string fileName)
        {
            try
            {
                Logger.Log("Loading legacy configuration from file: " + fileName, TraceEventType.Verbose);
                var legacyConfiguration = V1SchedulrConfiguration.Load(fileName);
                var pictureDefaults = account.Settings.PictureDefaults;
                var test = new System.Collections.ObjectModel.ObservableCollection<string>();
                var batchId = 1;
                if (account.QueuedPictures.Count > 0)
                {
                    batchId = account.QueuedPictures.Max(p => p.BatchId) + 1;
                }
                foreach (var legacyQueuedPicture in legacyConfiguration.QueuedPictures)
                {
                    var picture = new Picture
                    {
                        // The batch ID is calculated.
                        BatchId = batchId,

                        // Existing properties are taken from the legacy picture.
                        Description = legacyQueuedPicture.Description,
                        FileName = legacyQueuedPicture.FileName,
                        Tags = legacyQueuedPicture.Tags,
                        Title = legacyQueuedPicture.Title,
                        VisibilityIsFamily = legacyQueuedPicture.IsFamily,
                        VisibilityIsFriend = legacyQueuedPicture.IsFriend,
                        VisibilityIsPublic = legacyQueuedPicture.IsPublic,

                        // New properties are taken from the picture defaults.
                        ContentType = pictureDefaults.ContentType,
                        Safety = pictureDefaults.Safety,
                        License = pictureDefaults.License,

                        // Properties that are only valid for uploaded pictures are set to null.
                        DateUploaded = null,
                        PreviewUrl = null,
                        WebUrl = null,
                        PictureId = null
                    };
                    foreach (var legacyGroupId in legacyQueuedPicture.GroupIds)
                    {
                        picture.GroupIds.Add(legacyGroupId);
                    }
                    foreach (var legacySetId in legacyQueuedPicture.SetIds)
                    {
                        picture.SetIds.Add(legacySetId);
                    }

                    account.QueuedPictures.Add(picture);

                    // Increment the batch ID if the current picture should not be uploaded with the next.
                    if (!legacyQueuedPicture.UploadWithNext)
                    {
                        batchId++;
                    }
                }
                return legacyConfiguration.QueuedPictures.Count;
            }
            catch (Exception exc)
            {
                Logger.Log("Error while importing legacy configuration file", exc);
                throw;
            }
        }

        #endregion
    }
}